﻿package com.pandemicode.framework.utils {
	import flash.events.TimerEvent;
	import flash.utils.getTimer;
	import flash.utils.Timer;
	import org.osflash.signals.natives.NativeSignal;
	import org.osflash.signals.Signal;
	
	/**
	* @author Michael Lawrence
	* @version 1.0.0
	*/
	public class GlobalTimer {
		private var _time:int = 0;
		private var _startTime:int = 0;
		private var _timeDiff:int = 0;
		private var _paused:Boolean = false;
		private var _timer:Timer;
		private var _timerTicked:NativeSignal;
		private var _ticked:Signal;
		
		public function get ticked():Signal { return this._ticked; }
		
		/**
		 * The amount of time passed
		 */
		public function get time():int { return this._time; }
		
		/**
		 * The time the timer was started.
		 */
		public function get startTime():int { return this._startTime; }
		
		/**
		 * The amount of time elapsed since the last tick.
		 */
		public function get timeDiff():int { return this._timeDiff; }
		
		/**
		 * Whether or not the timer is running.
		 */
		public function get paused():Boolean { return this._paused; }
		public function set paused(value:Boolean):void {
			this._timeDiff = 0;
			this._time = getTimer();
			this._paused = value;
		}
		
		private static const _instance:GlobalTimer = new GlobalTimer(SingletonLock);
		/**
		 * A reference to the Singleton instance.
		 */
		public static function get instance():GlobalTimer {
			return _instance;
		}
		
		/**
		 * A timer to use globally.  This class cannot be instantiated. Instead use GlobalTimer.Instance.
		 * @param	lock	The singleton lock.
		 */
		public function GlobalTimer(lock:Class):void {
			// Verify that the lock is the correct class reference.
			if ( lock != SingletonLock )
				throw new Error("Invalid Singleton access.  Use GlobalTimer.Instance." );
			
			this._ticked = new Signal(GlobalTimer);
				
			this._startTime = getTimer();
			this._time = getTimer();
			
			this._timer = new Timer(1, 0);
			this._timerTicked = new NativeSignal(this._timer, TimerEvent.TIMER, TimerEvent);
			this._timerTicked.add(this._onTick);
			this._timer.start();
		}
		
		private function _onTick(e:TimerEvent):void {
			if(!this.paused) {
				this._timeDiff = getTimer() - this._time;
				
				this._time += this._timeDiff;
				
				this._ticked.dispatch(this);
			}
		}
	}
}

/*
* This is a private class declared outside of the package
* that is only accessible to classes inside of the GameTimer.as
* file.  Because of that, no outside code is able to get a
* reference to this class to pass to the constructor, which
* enables us to prevent outside instantiation.
*/
class SingletonLock { }